import axios from 'axios'
import router from '@/router'
import store from '@/store'
import to from 'await-to-js'
import { refreshToken } from '@/api/user'

export const baseURL = 'http://geek.itheima.net/'

// 新axios实例
const instance = axios.create({
  baseURL,
  timeout: 5000
})

// 请求拦截器
instance.interceptors.request.use(
  config => {
    const token = store.state.token
    if (token) config.headers.Authorization = `Bearer ${token}`
    return config
  },
  err => Promise.reject(err)
)

// 响应拦截器
instance.interceptors.response.use(
  res => res,
  async err => {
    // 如果响应状态码为401，说明是无效token错误
    if (err.response && err.response.status === 401) {
      // 提取局部公共代码为函数：删除token且跳转至登录页
      const delTokenAndGoLogin = () => {
        // 删除token
        store.commit('setToken', '')
        // 删除refreshToken
        store.commit('setRefreshToken', '')
        // 跳转至登录
        router.push(
          '/login?returnUrl=' + encodeURIComponent(router.currentRoute.fullPath)
        )
      }

      // 如果有refreshToken
      if (store.state.refreshToken) {
        // 先尝试刷新token
        const [err2, res2] = await to(refreshToken(store.state.refreshToken))
        // 如果刷新失败
        if (err2) {
          delTokenAndGoLogin()
        // 刷新成功
        } else {
          // 更新token
          store.commit('setToken', res2.data.data.token)
          // 再次发送上次失败的请求, err.config 是之前失败的请求配置
          return instance(err.config)
        }
      // 没有refreshToken
      } else {
        delTokenAndGoLogin()
      }
    }
    return Promise.reject(err)
  }
)

// 导出一个新axios实例调用接口的函数，返回值promise
export default ({ url, method = 'get', params, data, headers }) => {
  return to(instance({ url, method, params, data, headers }))
}
